package com.aljfce.business.profile.control;

import com.aljfce.business.profile.exception.CalendarNotFoundEception;
import com.aljfce.business.entity.Calendar;
import com.aljfce.business.entity.CalendarPK;
import com.aljfce.business.entity.Event;
import com.aljfce.business.entity.Notification;
import com.aljfce.business.entity.User;
import com.aljfce.business.utils.EventComparator;
import com.aljfce.business.utils.NotificationComparator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.GregorianCalendar;
import javax.ejb.Stateless;
import javax.inject.Named;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 * 
 * @author Antonio
 */
@Named
@Stateless
public class UserDataLoader {
    
    @PersistenceContext
    EntityManager em;
    
    /**
     * Default constructor
     */
    public UserDataLoader(){
    }
    
    //this is present in the design document but useless
    public void loadProfile(){
    }
    
    /**
     * This method seeks to user's events that begin in the current month
     *
     * @param user {@link User} object for which search the monthly events.
     * @return an {@link ArrayList} of {@link Event} objects sorted by the starting date of the events 
     * with all the user's monthly events. 
     * @throws IllegalArgumentException if {@link User} is null
     */ 
    public ArrayList<Event> loadMyMonthlyCalendar(User user) throws IllegalArgumentException, CalendarNotFoundEception {
        
        if (user == null) {
            throw new IllegalArgumentException("User cannot be null");
        }
        
        ArrayList<Event> monthlyEvents = new ArrayList<Event>();
        //the current date
        GregorianCalendar now = new GregorianCalendar();
        //all user's events
        ArrayList<Event> events = loadEventsBar(user);
        //to find only monthly events
        for(Event event : events){
            if(event.getStartingDate().getMonth()==now.get(GregorianCalendar.MONTH)&&
                    event.getStartingDate().getYear()==now.get(GregorianCalendar.YEAR)){
                monthlyEvents.add(event);
            }
        }
        //sorting ArrayList
        Collections.sort(monthlyEvents, new EventComparator());
        return monthlyEvents;
    }
    
    /**
     * This method seeks to user's events that begin in the current week
     *
     * @param user {@link User} object for which search the weekly events.
     * @return an {@link ArrayList} of {@link Event} objects sorted by the starting date of the events 
     * with all the user's weekly events. 
     * @throws IllegalArgumentException if {@link User} is null
     */
    public ArrayList<Event> loadMyWeeklyCalendar(User user) throws IllegalArgumentException, CalendarNotFoundEception{
        
        if (user == null) {
            throw new IllegalArgumentException("User cannot be null");
        }
        
        ArrayList<Event> weeklyEvents = new ArrayList<Event>();
        //the current date
        GregorianCalendar now = new GregorianCalendar();
        //all user's events
        ArrayList<Event> events = loadEventsBar(user);
        
        GregorianCalendar convertedEventDate = new GregorianCalendar();
        //to find only weekly events
        for(Event event : events){
            convertedEventDate.set(event.getStartingDate().getYear(), event.getStartingDate().getMonth(), event.getStartingDate().getDate());
            if(convertedEventDate.get(GregorianCalendar.MONTH)==now.get(GregorianCalendar.MONTH)&&
                    convertedEventDate.get(GregorianCalendar.YEAR)==now.get(GregorianCalendar.YEAR)&&
                    convertedEventDate.get(GregorianCalendar.WEEK_OF_MONTH)==now.get(GregorianCalendar.WEEK_OF_MONTH)){
                weeklyEvents.add(event);
            }
        }
        //sorting ArrayList
        Collections.sort(weeklyEvents, new EventComparator());
        return weeklyEvents;
    }
    
    /**
     * This method seeks to user's events that begin in the current day
     *
     * @param user {@link User} object for which search the daily events.
     * @return an {@link ArrayList} of {@link Event} objects sorted by the starting date of the events 
     * with all the user's daily events. 
     * @throws IllegalArgumentException if {@link User} is null
     */
    public ArrayList<Event> loadMyDailyCalendar(User user) throws IllegalArgumentException, CalendarNotFoundEception{
        
        if (user == null) {
            throw new IllegalArgumentException("User cannot be null");
        }
        
        ArrayList<Event> dailyEvents = new ArrayList<Event>();
        //the current date
        GregorianCalendar now = new GregorianCalendar();
        //all user's events
        ArrayList<Event> events = loadEventsBar(user);        
        //to find only daily events
        for(Event event : events){
            if(event.getStartingDate().getMonth()==now.get(GregorianCalendar.MONTH)&&
                    event.getStartingDate().getYear()==now.get(GregorianCalendar.YEAR)&&
                    event.getStartingDate().getDate()==now.get(GregorianCalendar.DAY_OF_MONTH)){
                dailyEvents.add(event);
            }
        }
        //sorting ArrayList
        Collections.sort(dailyEvents, new EventComparator());
        return dailyEvents;
    
    }
    
    /**
     * This method seeks for all user's events
     *
     * @param user {@link User} object for which search events.
     * @return an {@link ArrayList} of {@link Event} objects sorted by the starting date of the events 
     * with all the user's events.
     * @throws IllegalArgumentException if {@link User} is null 
     */
    public ArrayList<Event> loadEventsBar(User user) throws IllegalArgumentException, CalendarNotFoundEception{
        
        if (user == null) {
            throw new IllegalArgumentException("User cannot be null");
        }
        
        Calendar calendar;
        CalendarPK myCalendarPK = new CalendarPK(user.getEmail(),"default");        
        calendar = em.find(Calendar.class, myCalendarPK);
        if (calendar==null){
            throw new CalendarNotFoundEception("Calendar is not present in the persistence context");
        }
        
        ArrayList<Event> events = new ArrayList<>(calendar.getEventCollection());
        //sorting ArrayList
        Collections.sort(events, new EventComparator());
        
        return events;
    }
    
    /**
     * This method seeks for all user's notifications
     *
     * @param user{@link User} object for which search notifications.
     * @return an {@link ArrayList} of {@link Notification} objects sorted
     * by the starting date of the notifications with all the user's notifications. 
     * @throws IllegalArgumentException if {@link User} is null
     */
    public ArrayList<Notification> loadNotificationBar(User user) throws IllegalArgumentException{
        
        if (user == null) {
            throw new IllegalArgumentException("User cannot be null");
        }
        
        ArrayList<Notification> notifications = (ArrayList<Notification>) user.getNotificationCollection();
        //sorting ArrayList
        Collections.sort(notifications, new NotificationComparator());
        
        return notifications;
    }   
}
